/*
Controller for MCV framework structure
*/

#ifndef ALLEGROWRAPPER_H
#define ALLEGROWRAPPER_H

#include <allegro5/allegro.h>
#include <allegro5/allegro_primitives.h>
#include <vector>

#include "mvc/mymodel.h"
#include "mvc/myview.h"
#include "mvc/mycontroller.h"

class MyModel;
class MyView;
class MyController;

#define MASTER AllegroWrapper::Instance()

class AllegroWrapper : public MyController{
  private:
	/**
	 * A pointer to this controller once it has been initialized.
	 */
	static AllegroWrapper* _instance;


    ALLEGRO_DISPLAY* display;
    ALLEGRO_EVENT_QUEUE* queue;
    ALLEGRO_TIMER* timer;

    ALLEGRO_EVENT_SOURCE* keyboard_source;
    ALLEGRO_EVENT_SOURCE* mouse_source;
    ALLEGRO_EVENT_SOURCE* timer_source;
    ALLEGRO_EVENT_SOURCE* display_source;
    std::vector<ALLEGRO_EVENT_SOURCE*> event_sources;

    int screen_w, screen_h;
    float fps;

    void cleanup();

    // used to determine if redraw needed in event loop
    bool redraw;

    // used to kill event loop
    bool done;

    MyController* firstResponder;

    std::vector<MyController*> controllers;

  public:
    AllegroWrapper();

	/**
	 * Gives all simulation objects global access to the controller by 
	 * returning a pointer to it.
	 *
	 * @return a pointer to the Timer
	 */
	static AllegroWrapper* Instance();

    MyController* getFirstResponder();
    void setFirstResponder(MyController*);

    virtual void processEvent(ALLEGRO_EVENT*);

    bool initAll();

    bool init();
    bool initPrimitives();

    bool initKeyboard();
    bool initMouse();

    int getScreenW();
    void setScreenW(int);
    int getScreenH();
    void setScreenH(int);
    bool initDisplay();

    float getFPS();
    void setFPS(float);
    bool initTimer();

    bool initQueue();

    void go();

    // called by either the master view or master model to initiate redraw
    void needRedraw();
    
    // called by the master model to initiate application shutdown
    void makeDone();
};

#endif

